import {
  Component,
  ElementRef,
  EventEmitter,
  Input,
  OnInit,
  Output,
  Renderer2,
  ViewChild,
} from '@angular/core';
import { FormGroup } from '@angular/forms';
import { GridOptions } from '@ag-grid-community/core';
import { ApiService } from '@core/services/http/api.service';
import { GridConfigService } from '@core/config/grid-config.service';
import { deepClone, missing, replaceAll, type } from '../../../utils/utils';
import { SearchService } from '@core/services/search.service';
import { SubjectService } from '@core/services/events/subject.service';
import { ApesMessageService } from '@shared/apes/message';
import { Subject } from 'rxjs/internal/Subject';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { ExpressionService } from '@core/services/expression/ExpressionService';
import { UserAuthService } from '@core/services/user-auth.service';
import { AllModules, Module } from '@ag-grid-enterprise/all-modules';
import { format } from 'date-fns';
import { XlsxService } from '@shared/apes/xlsx';

export interface SearchFormMetadata {
  conditionField: any[],  // 查询条件
  api: string,  // 查询接口地址
  columnDefs: any[],     // grid 列头定义
  rowSelection: string // grid的选择模式 multiple  or single
  treeData: string,
  // global: any,
}

@Component({
  selector: 'apes-search-form',
  templateUrl: './apes-search-form.component.html',
})
export class ApesSearchFormComponent implements OnInit {
  private searchDebounce = 300;
  private searchSubject = new Subject<string>();
  modules: Module[] = AllModules;
  gridApi: any;
  gridColumnApi: any;
  autoGroupColumnDef;
  rowModelType;
  treeData = false;
  showCondition = true;

  prefixCls = 'apes-base-dialog';
  // 分页器
  loadingTotal = 0;
  pagination = {
    total: 0,
    currentPage: 1,
    lastRow: -1,
    pageSize: 20,
    pageTotal: 0,
    pages: 0,
  };

  rowData: any[];
  resultData: any;
  searchLoading = false; // 搜索按钮的动画
  gridOptions: GridOptions;
  currentRowIndex: number;

  title = '';
  downloadPage = 0;
  isDownloading = false;
  percent = 0;

  // form 定义相关
  @Input()
  form: FormGroup;
  @Input()
  model: any;
  @Input()
  options: any;
  @Input()
  searchFormMetadata: SearchFormMetadata;
  @Input() ctx = {};

  @ViewChild('searchBox', { static: false }) searchBox: ElementRef;
  @Output() onSearch = this.searchSubject.pipe(distinctUntilChanged(), debounceTime(this.searchDebounce));
  @Output() onFocus = new EventEmitter<string>();

  constructor(gridConfigService: GridConfigService,
              private renderer: Renderer2,
              private apiService: ApiService,
              protected subject: SubjectService,
              private msg: ApesMessageService,
              private searchService: SearchService,
              private expressionService: ExpressionService,
              private userAuthService: UserAuthService,
              private  xlsx: XlsxService,
              private userService: UserAuthService,
  ) {
    this.gridOptions = <GridOptions>{};
    this.gridOptions.localeText = gridConfigService.getLocaleText();
  }

  ngOnInit() {
    this.searchFormMetadata.columnDefs.forEach(element => {
        let hide = element.hideExpression || 'false';
        element.hide = this.expressionService.eval(hide, {});
        if (element.hasOwnProperty('changeCellStyle')) {
          let that = this;
          element.cellStyle = (params) => {
            let CellStyle = element['changeCellStyle'];
            let res = that.expressionService.eval(CellStyle, params);
            return res;
          };
        }
      },
    );
    this.ctx['platform'] = this.userService.getUserInfoObj() ? this.userService.getUserInfoObj().platform : ''; // 判断平台
    this.model['platform'] = this.ctx['platform'];
    if (this.searchFormMetadata.treeData === 'true') {
      this.treeData = true;
      this.autoGroupColumnDef = {
        cellRendererParams: {
          innerRenderer: function(params) {
            return params.data.name;
          },
        },
      };
      this.rowModelType = 'clientSide';
      this.showCondition = this.searchFormMetadata.conditionField.length > 0 ? true : false;
    } else {
      this.treeData = false;
      this.rowModelType = 'serverSide';
      this.gridOptions.cacheBlockSize = 20;
      this.gridOptions.infiniteInitialRowCount = 1;
      this.gridOptions.pagination = false;
      //this.gridOptions.maxBlocksInCache =100;
      this.gridOptions.paginationPageSize = this.pagination.pageSize;

      this.searchFormMetadata.conditionField.map((condition) => {
        if (condition.key === 'state') {
          if (type(condition.defaultValue) === 'object')
            condition.defaultValue = JSON.parse(condition.defaultValue);
        }
        if (!condition.templateOptions.hasOwnProperty('divCol')) {
          condition.templateOptions.divCol = 24;
        }
      });
    }
    this.searchSubject.pipe().subscribe(data => this.gridApi.setQuickFilter(data));
    // if (this.searchFormMetadata.hasOwnProperty('global')){
    //   this.interceptEventListener(this.searchFormMetadata.global.events);
    // }

    this.subject.subscribe(this.ctx, 'clickBtn', data => {
      this._search(true);
    });
  }

  ngAfterViewInit() {
    // 获取 container 元素
    let apesGrid = document.querySelector('.ag-theme-balham');
    // header:48,tabs:52,button:35,contentTop:8,contentBottom:8;
    const clienHeight = document.querySelector('.content').clientHeight;
    let containerHeight;
    let platform = this.userAuthService.getUserInfoObj() ? this.userAuthService.getUserInfoObj().platform : '';
    if (platform !== 'fn' && platform !== 'zt' && platform !== 'gys') {
      containerHeight = clienHeight - 8 - 45 - 105;
    } else {
      containerHeight = clienHeight - 8 - 20 - 105;
    }
    let apesRelevancyLink = document.querySelector('.apes-relevancy-link') ? document.querySelector('.apes-relevancy-link').clientHeight + 16 : 0;
    setTimeout(() => {
      let apesItemHeight;
      if (!this.treeData) {
        apesItemHeight = document.querySelector('.apes-item').clientHeight;
      } else {
        apesItemHeight = 25;
      }
      this.renderer.setStyle(apesGrid, 'height', containerHeight - apesItemHeight - apesRelevancyLink + 'px');
    }, 100);
  }


  _search(searchLoading): void {
    // 将分页器的数值改为初始数值
    this.pagination.total = 0;
    this.pagination.currentPage = 1;
    this.pagination.lastRow = -1;
    this.currentRowIndex = -1;

    this.queryData(searchLoading);
  }

  private queryData(searchLoading) {
    const conditionList = this.getConditionList(this.searchFormMetadata.conditionField);
    // 检查什么都不输入的情况下，不让查询
    if (!conditionList) {
      this.searchLoading = false;
      return;
    }
    const sendData = {
      condition: conditionList,
      size: this.pagination.pageSize,
      page: this.pagination.currentPage - 1,
      platform: this.ctx['platform'],
    };


    if (this.rowModelType == 'serverSide') {
      let dataSource = {
        rowCount: null,
        getRows: (params: any) => this.getRows(params, [], sendData),
      };
      //this.gridApi.setDatasource(dataSource);
      this.gridApi.setServerSideDatasource(dataSource);
    } else {
      this.apiService.post(this.searchFormMetadata.api, { 'body': JSON.stringify(sendData) }).subscribe(
        (body) => {
          if (body) {
            this.pagination.total = body.total;
            this.pagination.pageTotal = body.pages;
            let tempRowData: any;
            if (this.treeData === true) {
              tempRowData = body;
            } else {
              tempRowData = body.content;
            }

            this.rowData = [];
            this.gridOptions.api.setRowData(tempRowData);
            this.rowData = tempRowData;

            if (this.rowData.length === 0) this.msg.info(`未找到满足条件的数据`);
          }
          this.autoSizeAll();
          searchLoading = false;
        });
    }

  }

  private getRows(params: any, data: any, sendData: any) {
    sendData['size'] = this.pagination.pageSize;
    sendData['page'] = this.pagination.currentPage - 1;
    // TODO 检查返回值是否不为空数组
    this.apiService.post(this.searchFormMetadata.api, { 'body': JSON.stringify(sendData) })
      .subscribe((items) => {
        if (items) {
          this.pagination.total = items.total;
          const itemsLength = items.content.length;
          if (itemsLength > 0 && itemsLength >= this.pagination.pageSize) {
            this.pagination.currentPage = this.pagination.currentPage + 1;
          }
          if (itemsLength == 0 || itemsLength < this.pagination.pageSize) {
            this.pagination.lastRow = (this.pagination.currentPage - 1) * this.pagination.pageSize + itemsLength;
          }
          this.loadingTotal = this.pagination.lastRow !== -1 ? this.pagination.lastRow : params.request.endRow;
          params.successCallback(items.content, this.pagination.lastRow);
          if (itemsLength === 0 && this.pagination.lastRow <= 0) this.msg.info(`未找到满足条件的数据`);
          /*处理数据只有一行选中问题*/
          if (this.pagination.currentPage == 1 && itemsLength == 1) {
            this.subject.publish(this.ctx, this.subject.event_form_load, items.content[0]);
          }
        } else {
          params.successCallback([], 0);
        }
        this.searchLoading = false;
      });
  }

  onRowClick(params) {
    if ('submit' === this.ctx['states']) {
      this.gridApi.forEachNode((node) => {
        if (this.currentRowIndex === node.rowIndex) {
          node.setSelected(true);
        }
      });
      return false;
    }
    this.currentRowIndex = params.rowIndex;

    const selectedRow = this.gridOptions.api.getSelectedRows();

    this.resultData = selectedRow;
    if (this.treeData && this.searchFormMetadata.hasOwnProperty('secondaryApi')) {
      this.apiService.post(this.searchFormMetadata['secondaryApi'], { id: selectedRow[0].id }).subscribe(item => {
          this.subject.publish(this.ctx, this.subject.event_form_load, item);
        },
      );
    } else {
      this.subject.publish(this.ctx, this.subject.event_form_load, selectedRow[0]);
    }
  }

  onSelectionChanged() {
    // if (this.searchFormMetadata.rowSelection !== 'single') {
    //   return;
    // }
    // if ('submit' === this.ctx['states']) {
    //   this.gridApi.forEachNode((node) => {
    //     if (this.currentRowIndex === node.rowIndex) {
    //       node.setSelected(true);
    //     }
    //   });
    //   return false;
    // }
    // const selectedRow = this.gridOptions.api.getSelectedRows();
    //
    // this.resultData = selectedRow;
    // if (this.treeData && this.searchFormMetadata.hasOwnProperty("secondaryApi")){
    //   this.apiService.post(this.searchFormMetadata["secondaryApi"],{id:selectedRow[0].id}).subscribe( item =>{
    //        this.subject.publish(this.ctx, this.subject.event_form_load, item);
    //     }
    //   )
    // }else{
    //   this.subject.publish(this.ctx, this.subject.event_form_load, selectedRow[0]);
    // }
  }

  resetForm() {
    this.form.reset();
  }

  refreshRowData(data: any, btnId: any) {
    const rows = [];
    let add = true;
    let oldPath = '';
    let newPath = '';
    let bPath = false;
    this.gridApi.forEachNode((node) => {
      if (data.id === node.data.id) {
        if (btnId !== 'action_delete') {
          if (this.searchFormMetadata.treeData) {
            oldPath = deepClone(node.data.path);
            if (data.path != oldPath) {
              newPath = data.path;
              bPath = true;
            }
          }
          rows.push(data);
        }
        add = false;
      } else {
        if (this.searchFormMetadata.treeData && bPath && node.data.path == oldPath + '/' + node.data.id) {
          node.data.path = newPath + '/' + node.data.id;
        }
        rows.push(node.data);
      }
    });
    if (add) {
      rows.push(data);
    }
    this.gridOptions.api.setRowData(rows);
  }

  onPageIndexChange() {
    this.searchLoading = true;
    this.queryData(this.searchLoading);
  }

  /**
   * 功能：拼接查询条件
   * @returns {any[]}
   */
  getConditionList(conditionField: any): any[] {
    return this.searchService.getConditionList(conditionField, this.model);
  }

  onFilterTextBoxChanged() {
    let data = this.form.value['quickSearchInput'];
    this.searchSubject.next(data);
  }


  getDataPath(data) {
    return data.path.split('/'); // path: "Erica/Malcolm"
  }

  onGridReady(params) {
    this.gridApi = params.api;
    this.gridColumnApi = params.columnApi;
    // if (this.treeData) {
    //   this.apiService.post(this.searchFormMetadata.api, {'body': JSON.stringify({company:"1001"})}).subscribe(data => {
    //     this.rowData = data;
    //   });
    //  this.autoSizeAll();
    // }
  }

  autoSizeAll() {
    let allColumnIds = [];
    this.gridColumnApi.getAllColumns().forEach(column => {
      if (!column.colDef.hasOwnProperty('width')) {
        allColumnIds.push(column.colId);
      }

    });
    this.gridColumnApi.autoSizeColumns(allColumnIds);
  }

  /**
   * 功能：注册事件监听器
   * @param {string} topic
   */
  // interceptEventListener(events: any[]) {
  //   if (missing(events)) return;
  //   events.forEach(em => {
  //     em.type.split(',').forEach(type => {
  //       /**订阅事件**/
  //       this.subject.subscribe(this.ctx, type, data => {
  //         this.expressionService.evaluate(em.callback, {
  //           context: this.ctx,
  //           form: this.form,
  //           model: this.model,
  //           data: data,
  //         }, true);
  //       });
  //     });
  //   });
  // }


  /**
   * 下载功能
   * @param callBack
   * @private
   */
  _download(api, callBack) {
    if (this.rowModelType == 'clientSide') return;

    let downloadData = [];
    this.downloadPage = 0;
    this.isDownloading = true;

    let columnDefs = deepClone(this.searchFormMetadata.columnDefs);

    this.queryDownloadData(api, downloadData, columnDefs, callBack);
  }

  /**
   * 功能：查询后台数据(下载)
   */
  private queryDownloadData(api, data, col, callBack) {

    let totalQuantity = 300000; // 下载控制数

    const conditionList = this.getConditionList(this.searchFormMetadata.conditionField);
    // 检查什么都不输入的情况下，不让查询

    const sendData = {};
    sendData['noSum'] = false;
    sendData['condition'] = conditionList;
    sendData['size'] = 2000;
    sendData['page'] = this.downloadPage;
    sendData['queryid'] = api;
    sendData['customAction'] = false;
    sendData['customQuery'] = false;

    this.apiService.post('pub.query', { 'body': JSON.stringify(sendData) }).subscribe(
      (body) => {
        if (body) {

          if (body.total == 0) {
            this.msg.info(`查询结果为空`);
            this.isDownloading = false;
            // this.setButtonLoadingStatus('action_download', false);
            return;
          }

          //if (body.size) this.pagination.pageSize = body.size;
          body.content.forEach((i) => {
            data.push(i);
          });
          this.pagination.total = body.total;
          this.pagination.pages = body.pages;

          if (body.total > totalQuantity) {
            this.msg.info(`数据量过大！目前仅支持30W行以下数据下载`);
            this.isDownloading = false;
            this.percent = 100;
            // this.setButtonLoadingStatus('action_download', false);
            return;
          }

          //需求要求放开控制 初50页 10w,原100页 20w,
          // if (this.pagination.total <= data.length || this.downloadPage >= 250)
          if (this.pagination.total <= data.length) {
            // if (this.downloadPage >= 250) {
            //   this.msg.info(`数据量过大！目前仅支持20W行数据下载`);
            // }
            this.generateExcl(data, col);
            this.isDownloading = false;
            this.percent = 100;
            callBack(true);
            // this.setButtonLoadingStatus('action_download', false);
          } else {
            this.downloadPage = this.downloadPage + 1;
            this.percent = Math.round(this.downloadPage / this.pagination.pages * 100);
            this.queryDownloadData(api, data, col, callBack);
          }
        } else {
          this.msg.info(`下载接口报错！`);
        }

      }, () => {
        this.autoSizeAll();
      });
  }

  /**
   * 生成excl
   * @param data
   * @param col
   * @private
   */
  private generateExcl(downloadData, col) {
    let exportName = this.title && this.title != '' ? this.title : '导出文件';
    exportName += format(new Date(), 'YYYYMMDDHHmm');
    let data = [];
    let localCol = [];
    data = [col.map(i => i.headerName)];
    downloadData.forEach((i, index) => {
        if (index == 0) {
          let bExpansion = false;
          col.map((c) => {
              let colName = (c.field as string).toUpperCase();
              let value = deepClone(i[colName]);
              if (value instanceof Object) {
                localCol = [...localCol, ...this.objectToExpansion(value, c)];
                bExpansion = true;
              } else {
                c.fieldMeta = c.field;
                localCol.push(c);
              }
            },
          );
          if (bExpansion) data = [localCol.map(i => i.headerName)];
        }
        data.push(
          localCol.map(c => {
              let colName = (c.field as string).toUpperCase();
              let value = deepClone(i[colName]);
              let key = replaceAll(c.field, c.fieldMeta, '');
              if (value instanceof Object) {
                if (c['exportFormatter']) {
                  let expression = c['exportFormatter'];
                  value = this.expressionService.evaluate(expression, {
                    value: value,
                  });
                } else {
                  value = value[key];
                }
                if (value == undefined) {
                  value = i[c.field as string].description;
                }
              }
              // 处理序号字段为空的问题
              if (c.field === 'operation') value = data.length;

              return value;
            },
          ));
      },
    );
    this.xlsx.export({
      filename: exportName += '.xlsx',
      sheets: [
        {
          data: data,
          name: '数据',
        },
      ],
    });
  }

  /**
   *  下载有对象展开数据
   */
  private objectToExpansion(value, c) {
    let columns = [];
    for (const key in value) {
      let localKey = key.toUpperCase();
      if (localKey == 'ID') {
        columns.push({ field: c.field + key, headerName: c.headerName + '编码', fieldMeta: c.field });
      } else if (localKey == 'NAME') {
        columns.push({ field: c.field + key, headerName: c.headerName + '名称', fieldMeta: c.field });
      }
    }
    return columns;
  }

}
